/*
 * drv_pwm.c
 *
 *  Created on: Oct 3, 2013
 *      Author: Omar Sevilla
 */
#include "stdtypedef.h"
#include "derivative.h"
#include "drv_pwm.h"
#include "drv_adc8.h" //for function analog_pwm
#include "app_indicator.h"

extern	T_UBYTE	rub_ModeReg;
void init_pwm(void){

	//Set TPMR Clock Source
	SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1);
	SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;

	
	//Set Clock Ports
	SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK|SIM_SCGC5_PORTD_MASK;
	//Set TMPR CLOCK SOURCE
	SIM_SCGC6 |= SIM_SCGC6_TPM2_MASK|SIM_SCGC6_TPM0_MASK;
	
	TPM2_C0V = 0x0;
	TPM2_C1V = 0x0;
	TPM0_C1V = 0x0;
	/*Initialise PTD1 as PWM*/
	PORTD_PCR1 = PORT_PCR_MUX(0x4); //Set PTD1 as PWM Pin TPM0_CH1(Alternative 4)
	PORTB_PCR18 = PORT_PCR_MUX(0x3); //Set PTD1 as PWM Pin TPM0_CH1(Alternative 4)
	PORTB_PCR19 = PORT_PCR_MUX(0x3); //Set PTD1 as PWM Pin TPM0_CH1(Alternative 4)

	TPM0_CNT = 0;
	TPM0_MOD = 0xFF;
		
	TPM0_SC = TPM_SC_CMOD(1);
	TPM0_C1SC = 0b101100; //Edge Aligned PWM LOW-TRUE mode
		
	TPM0_C1V = 0x0;
	
	TPM2_CNT = 0;
	TPM2_MOD = 0xFF;
	
	TPM2_SC = TPM_SC_CMOD(1);
	TPM2_C0SC = 0b101100; //Edge Aligned PWM LOW-TRUE mode
	TPM2_C1SC = 0b101100; //Edge Aligned PWM LOW-TRUE mode
	
	TPM2_C0V = 0x0;
	TPM2_C1V = 0x0;


}

void set_pwm(T_UBYTE T_UBYTE_PWMChannel,T_UWORD T_UWORD_PWMValue){

	switch(T_UBYTE_PWMChannel){
	case PWM_RED:
		TPM2_C0V = T_UWORD_PWMValue; 	//Set PWM RED
		break;
	case PWM_GREEN:
		TPM2_C1V = T_UWORD_PWMValue; 	//Set PWM GREEN
		break;
	case PWM_BLUE:
		TPM0_C1V = T_UWORD_PWMValue;	//Set PWM BLUE
		break;
	case PWM_CYAN:
		TPM0_C1V = T_UWORD_PWMValue;	//Set PWM CYAN
		TPM2_C1V = T_UWORD_PWMValue;
		break;
	case PWM_YELLOW:
		TPM2_C0V = T_UWORD_PWMValue;	//Set PWM YELLOW
		TPM2_C1V = T_UWORD_PWMValue;
		break;
	case PWM_PURPLE:
		TPM2_C0V = T_UWORD_PWMValue;	//Set PWM PURPLE
		TPM0_C1V = T_UWORD_PWMValue;
		break;
	case PWM_WHITE:
		TPM2_C0V = T_UWORD_PWMValue;
		TPM2_C1V = T_UWORD_PWMValue;	//Set PWM WHITE
		TPM0_C1V = T_UWORD_PWMValue;
	default:
		break;
	}
}

void pwm_fading(T_UBYTE T_UBYTE_FadingValue){
	static T_UWORD counter=0;
	static T_UBYTE lub_Direction=0;
	set_pwm(T_UBYTE_FadingValue,counter);
	if(lub_Direction == 0){
		 counter += 0x00FF;
		 if(counter >= 1000)		//Max Value
			 lub_Direction = 1;
	}
	else{
		 counter -= 0x00FF;
		 if(counter < 0x00100 ){
			 counter = 0;
			 lub_Direction = 0;
		 }
	}
}


void analog_pwm(void){
	extern 	T_UWORD	ruw_RedValue,
					ruw_GreenValue,
					ruw_BlueValue,
					ruw_ExtRedValue,
					ruw_ExtGreenValue,
					ruw_ExtBlueValue;
	if(rub_ModeReg == EXTERNAL){
		//red
		set_pwm(PWM_RED,ruw_ExtRedValue);
		//green
		set_pwm(PWM_GREEN,ruw_ExtGreenValue);
		//blue
		set_pwm(PWM_BLUE,ruw_ExtBlueValue);
	}
	else{
		set_pwm(PWM_RED,ruw_RedValue);
		//green
		set_pwm(PWM_GREEN,ruw_GreenValue);
		//blue
		set_pwm(PWM_BLUE,ruw_BlueValue);
	}
}


void secuencial_pwm(T_UBYTE T_UBYTE_SecuencialControl){
	switch(T_UBYTE_SecuencialControl){
	case 0:
		set_pwm(PWM_BLUE,0x00);
		set_pwm(PWM_GREEN,0x00);
		pwm_fading(PWM_RED);
		break;
	case 1:
		set_pwm(PWM_BLUE,0x00);
		set_pwm(PWM_RED,0x00);
		pwm_fading(PWM_GREEN);
		break;
	case 2:
		set_pwm(PWM_RED,0x00);
		set_pwm(PWM_GREEN,0x00);
		pwm_fading(PWM_BLUE);
		break;
	case 3:
		set_pwm(PWM_RED,0x00);
		pwm_fading(PWM_CYAN);
		break;
	case 4:
		set_pwm(PWM_BLUE,0x00);
		pwm_fading(PWM_YELLOW);
		break;
	case 5:
		set_pwm(PWM_GREEN,0x00);
		pwm_fading(PWM_PURPLE);
		break;
	case 6:
		pwm_fading(PWM_WHITE);
		break;
	default:
		break;
	}
}
